package org.one.stone.soup.wiki.multicaster;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GraphicsDevice;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.one.stone.soup.grfx.ImageFactory;
import org.one.stone.soup.screen.recorder.DesktopScreenRecorder;
import org.one.stone.soup.screen.recorder.ScreenPlayer;
import org.one.stone.soup.screen.recorder.ScreenPlayerListener;
import org.one.stone.soup.screen.recorder.ScreenRecorder;
import org.one.stone.soup.screen.recorder.ScreenRecorderListener;
import org.one.stone.soup.stringhelper.StringGenerator;
import org.one.stone.soup.wiki.client.WikiClient;
import org.one.stone.soup.wiki.webcam.multicaster.applet.WebCamRecorder;
import org.one.stone.soup.xml.XmlElement;
public class MulticasterApplet extends JApplet implements ActionListener,ScreenRecorderListener,ScreenPlayerListener,KeyListener{
private static final int WAITING = 1;
private static final int RECORDING = 2;
private static final int PLAYING = 3;
private WikiClient client;
private boolean streamExists = false;
private Timer timer;
private String streamId = null;
private String pageName = null;
private int port;
private String host;
private String root;
private Socket socket;
private String deviceName;
private ScreenRecorder recorder;
private ScreenPlayer player;
private int frameCount=0;
private long startTime;
private JButton viewButton;
private JLabel viewLabel;
private ImageIcon view;
private boolean fullScreen=false;
private boolean playing;
private boolean recording;
private int currentMode = 0;
private JFrame fullScreenFrame;
private JPanel recordButtons;
private JPanel stopButtons;
private Image waitingImage;
private Image image;
private int viewWidth = -1;
private int viewHeight = -1;
public class CheckForStream extends TimerTask
{
public void run()
{
checkForStream();
}
}
public void init(){
try{
getContentPane().setBackground(Color.black);
host = getParameter("host");
if(host==null)
{
host = getCodeBase().getHost();
}
deviceName = getParameter("webCam");
String portString = getParameter("port");
if(portString!=null)
{
port = Integer.parseInt(portString);
}
else
{
port = getCodeBase().getPort();
if(port==-1)
{
port=80;
}
}
root = host+":"+port;
client = new WikiClient("http://"+root,null,null);
waitingImage = getImage(new URL("http://"+root+"/OpenForum/Images/open-forum.png"));
view = new ImageIcon( waitingImage );
viewButton = new JButton(view);
viewButton.setBackground(Color.black);
viewButton.setToolTipText("View full screen. Press F11 to return.");
viewButton.setActionCommand("fullScreen");
viewButton.addActionListener(this);
viewButton.setBorderPainted(false);
add( viewButton,BorderLayout.CENTER );
viewLabel = new JLabel(view);
viewLabel.setBackground(Color.black);
recordButtons = new JPanel();
recordButtons.setBackground(Color.black);
ImageIcon icon = new ImageIcon( getImage(new URL("http://"+root+"/OpenForum/Images/icons/png/webcam.png")) );
JButton button = new JButton( icon );
button.setToolTipText("Web Cast from your WebCam");
button.setActionCommand("castWebCam");
button.addActionListener(this);
recordButtons.add( button );
icon = new ImageIcon( getImage(new URL("http://"+root+"/OpenForum/Images/icons/png/monitor.png")) );
button = new JButton( icon );
button.setToolTipText("Web Cast from your Desktop");
button.setActionCommand("castScreen");
button.addActionListener(this);
recordButtons.add( button );
stopButtons = new JPanel();
stopButtons.setBackground(Color.black);
icon = new ImageIcon( getImage(new URL("http://"+root+"/OpenForum/Images/icons/png/cancel.png")) );
button = new JButton( icon );
button.setToolTipText("Stop Web Cast");
button.setActionCommand("stop");
button.addActionListener(this);
stopButtons.add( button );
pageName=getParameter("pageName");
if(pageName==null)
{
pageName=getDocumentBase().toExternalForm();
}
streamId=getParameter("id");
if(streamId==null)
{
streamId=getDocumentBase().toExternalForm();
}
doLayout();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void start()
{
currentMode = 0;
setMode(WAITING);
timer = new Timer("Stream Checker");
timer.schedule(new CheckForStream(),1000,10000);
System.out.println("Multicaster Applet build 008");
}
public void stop()
{
timer.cancel();
timer = null;
if(recording)
{
recorder.stopRecording();
recorder = null;
}
if(playing)
{
player.stop();
player = null;
}
setMode(WAITING);
currentMode = 0;
}
public void destroy()
{
if(recording)
{
recorder.stopRecording();
recorder = null;
}
if(playing)
{
player.stop();
player = null;
}
if(timer!=null)
{
timer.cancel();
timer = null;
}
}
public void checkForStream()
{
if(playing)
{
return;
}
startCastPlayer();
}
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("castWebCam"))
{
startWebCamCaster();
}
else if(e.getActionCommand().equals("castScreen"))
{
startScreenCaster();
}
else if(e.getActionCommand().equals("fullScreen"))
{
toggleFullScreen();
}
else if(e.getActionCommand().equals("stop"))
{
recorder.stopRecording();
}
}
private void setMode(int mode)
{
if(mode==currentMode)
{
return;
}
if(recording && mode==PLAYING)
{
currentMode = RECORDING;
return;
}
if(fullScreen==true)
{
toggleFullScreen();
}
switch(currentMode)
{
case WAITING:
remove(recordButtons);
break;
case RECORDING:
remove(stopButtons);
break;
case PLAYING:
break;
}
currentMode = mode;
switch(currentMode)
{
case WAITING:
showNewImage(waitingImage);
add(recordButtons,BorderLayout.SOUTH);
recordButtons.invalidate();
break;
case RECORDING:
add(stopButtons,BorderLayout.SOUTH);
stopButtons.invalidate();
break;
case PLAYING:
break;
}
validate();
repaint();
}
public void startWebCamCaster()
{
try{
XmlElement header = new XmlElement("Recorder");
header.addAttribute("id",pageName+"/"+streamId);
Rectangle screen = new Rectangle( Toolkit.getDefaultToolkit ().getScreenSize() );
socket = new Socket(host,port);
socket.getOutputStream().write( ("GET /OpenForum/Multicaster/Share HTTP/1.1\r\n").getBytes() );
socket.getOutputStream().write( ("\r\n\r\n").getBytes() );
socket.getOutputStream().write(header.toXml().getBytes());
socket.getOutputStream().flush();
recorder = new WebCamRecorder(socket.getOutputStream(),this,deviceName);
recorder.startRecording();
recording = true;
setMode(RECORDING);
waitForCast();
startCastPlayer();
//text.setText("WebCast ID:"+id);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
public void startScreenCaster()
{
try{
XmlElement header = new XmlElement("Recorder");
header.addAttribute("id",pageName+"/"+streamId);
Rectangle screen = new Rectangle( Toolkit.getDefaultToolkit ().getScreenSize() );
socket = new Socket(host,port);
socket.getOutputStream().write( ("GET OpenForum/Multicaster/Share HTTP/1.1\r\n").getBytes() );
socket.getOutputStream().write( ("\r\n\r\n").getBytes() );
socket.getOutputStream().write(header.toXml().getBytes());
socket.getOutputStream().flush();
recorder = new DesktopScreenRecorder(socket.getOutputStream(),this);
recorder.startRecording();
recording = true;
setMode(RECORDING);
waitForCast();
startCastPlayer();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
public void waitForCast()
{
while(streamExists==false)
{
streamExists = client.getBoolean("OpenForum/Multicaster/CheckAvailability?id="+pageName+"/"+streamId);
try{Thread.sleep(1000);}catch(Exception e){}
}
}
public void startCastPlayer()
{
try{
streamExists = client.getBoolean("OpenForum/Multicaster/CheckAvailability?id="+pageName+"/"+streamId);
if(streamExists==false)
{
return;
}
//XmlElement header = new XmlElement("Player");
//header.addAttribute("id",pageName+"/"+streamId);
//header.addChild("alias").addValue( StringGenerator.generateUniqueId() );
/*socket = new Socket(host,port);
InputStream iStream = socket.getInputStream();
socket.getOutputStream().write( ("GET /OpenForum/Multicaster/Play?id="+pageName+"/"+streamId+"&alias="+StringGenerator.generateUniqueId()+" HTTP/1.1\r\n").getBytes() );
socket.getOutputStream().write( ("\r\n\r\n").getBytes() );*/
//socket.getOutputStream().write(header.toXml().getBytes());
//socket.getOutputStream().flush();
InputStream iStream = new URL("http://"+host+":"+port+"/OpenForum/Multicaster/Play?id="+pageName+"/"+streamId+"&alias="+StringGenerator.generateUniqueId()).openStream();
player = new ScreenPlayer(iStream,this);
player.setRealtime(true);
frameCount=0;
player.play();
//startTime = System.currentTimeMillis();
//text.setText("Connected to "+address+":"+port);
playing = true;
if(recording)
{
viewButton.setToolTipText(null);
viewButton.setActionCommand("no action");
}
else
{
viewButton.setToolTipText("View full screen. Press F11 to return.");
viewButton.setActionCommand("fullScreen");
}
setMode(PLAYING);
}
catch(Exception e)
{
e.printStackTrace();
return;
}
}
public void frameRecorded(boolean arg0) throws IOException {
frameCount++;
}
public void recordingStopped() {
if(recorder instanceof WebCamRecorder)
{
try{
((WebCamRecorder)recorder).stopPlayer();
}
catch(Exception e){}
}
recorder = null;
recording = false;
setMode(WAITING);
}
public void newFrame() {
if(frameCount==0)
{
player.pause();
}
frameCount++;
long time = System.currentTimeMillis()-startTime;
String seconds = ""+time/1000;
String milliseconds = ""+time%1000;
milliseconds = StringGenerator.pad(milliseconds,4,'0')+milliseconds;
}
public void playerStopped() {
player=null;
playing = false;
setMode(WAITING);
}
public void showNewImage(Image image) {
if(this.image==null && image!=waitingImage)
{
this.image = image;
viewWidth = this.getWidth();
viewHeight = this.getHeight();
}
if(fullScreen==false)
{
try{
image = ImageFactory.resizeImage(image,viewWidth,viewHeight,true);
}
catch(Exception e)
{
e.printStackTrace();
}
}
view.setImage(image);
if(fullScreen)
{
viewLabel.setSize(image.getWidth(this),image.getHeight(this));
viewLabel.setIcon(view);
}
validate();
repaint();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_F11)
{
toggleFullScreen();
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
private void toggleFullScreen()
{
GraphicsDevice device = this.getGraphicsConfiguration().getDevice();
if(device.isFullScreenSupported())
{
if(fullScreen==false)
{
remove( viewButton );
fullScreenFrame = new JFrame();
fullScreenFrame.setBackground(Color.black);
fullScreenFrame.setUndecorated(true);
fullScreenFrame.addKeyListener(this);
fullScreenFrame.setLayout( new FlowLayout() );
fullScreenFrame.add( viewLabel );
device.setFullScreenWindow(fullScreenFrame);
this.setVisible(true);
fullScreen = true;
showNewImage(image);
}
else
{
fullScreenFrame.remove( viewLabel );
add( viewButton,BorderLayout.CENTER );
device.setFullScreenWindow(null);
fullScreenFrame.dispose();
fullScreenFrame=null;
this.setVisible(true);
fullScreen = false;
showNewImage(image);
}
}
}
}